Skip to main content

Roam

Roam is a game initialization framework that aims to provide an easy way to boot up various sections of your game. It is based off the popular Roblox framework Knit, but stripped of excess parts. Roam allows you to create singleton objects, known as Services on the Server and Controllers on the Client, and have them initialize automatically and without major issue when you boot up your game.

info

Any module suffixed by the word Controller or Service will be automatically required by Roam on game boot.

Usage

Within your Service and Controller modules you should have each one return a table that has the methods :RoamInit() and :RoamStart(). [Note: One or both of these methods can technically be excluded if not needed].

local MyService = {}

function MyService:RoamInit()
end

function MyService:RoamStart()
end

return MyService

You must also register the Service to Roam with Roam.registerService so that it queues the table into the bootlist. Roam.registerService takes the Service table as the first argument and the name of the service as the second argument. This would be typically be placed immediately prior to the module's final return. Forgetting to do this will result in your Roam methods never being called.

local Roam = Import("Roam")
Roam.registerService(MyService, "MyService")
info

Alternatively to Roam.registerService you can use Roam.createService when creating your service table

local MyService = Roam.createService("MyService")

:RoamInit()

This method should be used to initialize your singleton with any values it needs to be ready for use. You should not access other services within this method as they may not yet be initialized.

:RoamStart()

This method should be used to begin any gameloop logic that you need handled. This method is spawned asynchronously within a new thread so it is safe to yield here if needed. All other services should be safe to access at this point.

Other Methods

You can also add your own methods to the service if you want. Any method that is expected to be used post RoamInit should be accessed/denoted with the colon operator :. Methods that are able to be used prior to RoamInit should be accessed/denoted with the period operator ., these are known as Static Methods, if you arent familiar with typical OOP conventions. Static Methods should also have a @tag static marker in their method header to help identify them.

--[=[
@tag static
A method intended to be accessed at any time.
]=]
function MyService.SomeStaticMethod()
end

--[=[
A method intended to be accessed only after RoamInit
]=]
function MyService:SomeDynamicMethod()
end

Boot Execution Model

1) Game Start
2) Collect and require all modules with proper suffixes
3) Call for Roam to Start
4) For each table registered to Roam through Roam.registerService:
5) If table has a method :RoamInit then call it within a promise.

6) Once all the created :RoamInit Promises are resolved then continue.

7) For each table registered to Roam through Roam.registerService:
8) If table has a method :RoamStart then call it within a new deffered thread.

If you ever encounter a race condition within your code where you need to ensure that Roam has started or need to wait for it to start, you can use Roam.onStart() which returns a promise that will resolve when Roam has fully started.